package com.io.netty.protocoltcp;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import java.nio.charset.Charset;
import java.util.UUID;

//
public class MyServerHandler extends SimpleChannelInboundHandler<MessageProtocol>{
    private int count;

    //每接收一次数据都会调用一次这个方法，
    // 也就是说这个方法调用的次数是跟编器、解码器中的方法调用次数是一样的
    //MessageProtocol的对象msg是直接从list集合的最后面取的？不然的话，就跟前面自己猜测的不一样
    //这一点不是很清楚。。。
    protected void channelRead0(ChannelHandlerContext ctx, MessageProtocol msg) throws Exception {

        //接收到数据，并处理
        int len = msg.getLen();
        byte[] content = msg.getContent();
        System.out.println();
        System.out.println();
        System.out.println();
        System.out.println("服务器接收到信息如下");
        System.out.println("长度=" + len);
        System.out.println("内容=" + new String(content, Charset.forName("utf-8")));
        System.out.println("服务器接收到消息包数量=" + (++this.count));

        //回复消息，随机生成一个UUID的字符串
        String responseContent = UUID.randomUUID().toString();
        int responseLen = responseContent.getBytes("utf-8").length;
        byte[]  responseContent2 = responseContent.getBytes("utf-8");
        //构建一个协议包
        MessageProtocol messageProtocol = new MessageProtocol();
        messageProtocol.setLen(responseLen);
        messageProtocol.setContent(responseContent2);
        //对象是不可以直接在网络中进行传输的，在netty中需要把这个放入缓冲区中，有一点要注意的是
        //在编码是缓冲区中放的内容并不是整个对象，而是对象中封装的数据的长度和数据的内容，
        //经过这样处理之后再借用通道将数据从网络中传输过去。并且不会发生粘包问题，
        //因为数据内容的长度和内容都已经知道了，读取的时候按照这个规则来读就行了
        //提示一下：在nio中也是需要放在缓冲区中借用通道才能进行传输，bio中是
        //通过流将对象放入Socket中才能进行传输的（猜测：bio中流应该会将数据变成字节，因为只有字节才能在网络中进行传输）
        ctx.writeAndFlush(messageProtocol);
    }

    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //cause.printStackTrace();
        ctx.close();
    }

}
